use std::sync::Arc;

use axum::{
    middleware::from_extractor_with_state,
    routing::{delete, get, post, put},
    Router,
};

use crate::{jwt::AdminClaimsData, middleware::RequiredAuth, AppState};

pub mod aggregation;
pub mod profile;
pub mod url;
pub mod user;

pub fn init_router(state: Arc<AppState>) -> Router {
    let r = Router::new()
        .nest("/agg", aggregation_router(state.clone()))
        .nest("/profile", profile_router(state.clone()))
        .nest("/url", url_router(state.clone()))
        .nest("/user", user_router(state.clone()));

    Router::new()
        .nest("/admin", r)
        .layer(from_extractor_with_state::<
            RequiredAuth<AdminClaimsData>,
            Arc<AppState>,
        >(state.clone()))
}

fn aggregation_router(state: Arc<AppState>) -> Router {
    Router::new()
        .route("/", get(aggregation::index))
        .with_state(state)
}

fn profile_router(state: Arc<AppState>) -> Router {
    Router::new()
        .route("/change-password", post(profile::change_password))
        .with_state(state)
}

fn url_router(state: Arc<AppState>) -> Router {
    Router::new()
        .route("/", post(url::add).get(url::list))
        .route("/:id", put(url::edit).delete(url::del))
        .with_state(state)
}

fn user_router(state: Arc<AppState>) -> Router {
    Router::new()
        .route("/", get(user::list).post(user::add).put(user::edit))
        .route("/freeze", post(user::freeze))
        .route("/active", post(user::active))
        .route("/pending", post(user::pending))
        .route("/:id", delete(user::del))
        .with_state(state)
}
